package com.kingdee.eas.custom.aoyuan.aytime.bizbill.app;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.kingdee.bos.Context;
import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.bos.metadata.entity.FilterItemInfo;
import com.kingdee.bos.metadata.entity.SorterItemCollection;
import com.kingdee.bos.metadata.entity.SorterItemInfo;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.eas.custom.aoyuan.aytime.basedata.ScheduleEntryInfo;
import com.kingdee.eas.custom.aoyuan.aytime.bizbill.CardRecordCollection;
import com.kingdee.eas.custom.aoyuan.aytime.bizbill.CardRecordFactory;
import com.kingdee.eas.custom.aoyuan.aytime.bizbill.CardRecordInfo;

public class AttenUtil {
	/**
	 * 第一班开始打卡是否成功
	 * 
	 * @param schEntry
	 *            班表明细
	 * @param cards
	 * @return
	 */
	public TimeParam isFinishStartCardByOffice1(Context ctx,ScheduleEntryInfo schEntry,
			List cards,String personid, Date d) {
		//前提打卡时间
		int aheadTime=120;
		if(schEntry.getSb1()!=null)
		{
			aheadTime=schEntry.getSb1().intValue();			
		}
		//迟到时间
		int lateDealLine=0;
		if(schEntry.getLateTime()!=null)
		{
			lateDealLine=schEntry.getLateTime().intValue();
		}
		//早退时间
		int earlyTime=0;
		if(schEntry.getEarlyTime()!=null)
		{
			//earlyTime=schEntry.getEarlyTime().intValue();
		}
		TimeParam param = new TimeParam();
		if (schEntry.getSt1() != null) {
			// 班表第一打卡时间
			long stm = schEntry.getSt1().getMinutes()
					+ schEntry.getSt1().getHours() * 60;
			long etm=schEntry.getEt1().getMinutes()+ schEntry.getEt1().getHours() * 60;
			//该班第一班下班时间减去早退时间
			long etm1 = etm-earlyTime;
			
			//第二天
			if(stm>etm)
			{
				etm1+=24*60;
				etm+=24*60;
			}
			// 提前打卡
			long roundtm = stm - aheadTime;
			long lateRoundtm = stm + lateDealLine;
			if(roundtm<=0)
			{
				//0点上班，在前一天打卡和当天
				ArrayList yesterList=getCardRecordYesterDay(ctx,personid,d);
				
				//当天开始时间
				long tmpStm=stm+24*60;
				//提前打卡
				long tmpRoundtm=tmpStm - aheadTime;
				long tmpLateRoundtm=tmpStm+lateDealLine;
				
				// 时间范围内卡
				for (int i = 0; i < yesterList.size(); i++) {
					//昨天与当天打卡记录
					CardRecordInfo recordInfo = (CardRecordInfo) yesterList.get(i);
					//当天
					long ftm = recordInfo.getBizTime().getMinutes()
					+ recordInfo.getBizTime().getHours() * 60;
					if (compWorkAndCurrByDate(schEntry.getSchDate(),recordInfo.getBizDate()))  {
						//当天
						ftm+=24*60;
					}
					if(tmpRoundtm<=ftm&&tmpStm>=ftm)
					{
						// 在时间内打卡，找到第一次打卡时间
						param.isFinish = true;
						param.isFind=true;
						// 非请假单虚拟记录,请假时间不作记录
						if(recordInfo.getId()!=null)
						{
							//实际打卡
							param.cardTime = recordInfo.getBizTime();						
						}
						break;							
					}else if(ftm>tmpStm&&ftm<=etm)  //if(ftm>tmpStm&&ftm<=tmpLateRoundtm) 超过预设迟到范围，就算旷工
					{
						// 迟到分钟
						long lateMin = ftm - tmpStm;
						param.isFinish = false;
						param.isFind=true;
						// 非请假单虚拟记录，请假时间不作记录
						if(recordInfo.getId()!=null)
						{
							//实际打卡
							param.cardTime = recordInfo.getBizTime();				
						}
						param.lateTime = lateMin;
						break;
					}
					//表示没有找到任何打卡记录，计算该班次第一班的旷工时间
					if(!param.isFind)
					{
						param.absentTime=etm-stm;
					}		
				}
				
			}else
			{
				// 时间范围内卡
				for (int i = 0; i < cards.size(); i++) {
					CardRecordInfo recordInfo = (CardRecordInfo) cards.get(i);
					//第二天，跳过计算
					if (!compWorkAndCurrByDate(schEntry.getSchDate(),recordInfo.getBizDate()))  {
						continue;
					}
					//打卡时间
					long ftm = recordInfo.getBizTime().getMinutes()
							+ recordInfo.getBizTime().getHours() * 60;
					if (roundtm <= ftm && ftm <= stm) {
						// 在时间内打卡，找到第一次打卡时间
						param.isFinish = true;
						param.isFind=true;
						// 非请假单虚拟记录,请假时间不作记录
						if(recordInfo.getId()!=null)
						{
							//实际打卡
							param.cardTime = recordInfo.getBizTime();						
						}
						break;
						//else if (ftm > stm && ftm <= lateRoundtm) 只要有打卡都算迟到，不算旷工
					} else if (ftm > stm && ftm <= etm) {
						// 迟到分钟
						long lateMin = ftm - stm;
						param.isFinish = false;
						param.isFind=true;
						// 非请假单虚拟记录，请假时间不作记录
						if(recordInfo.getId()!=null)
						{
							//实际打卡
							param.cardTime = recordInfo.getBizTime();				
						}
						param.lateTime = lateMin;
						break;
					}/*else if(ftm>lateRoundtm&&etm1>ftm)
					{
						//旷工 时间
						long absentTime=ftm-stm;
						param.absentTime=absentTime;
						param.isFind=true;
						if(recordInfo.getId()!=null)
						{
							//实际打卡
							param.cardTime = recordInfo.getBizTime();				
						}			
						break;
					}*/
				}
				//表示没有找到任何打卡记录，计算该班次第一班的旷工时间
				if(!param.isFind)
				{
					param.absentTime=etm-stm;
				}				
			}

		}
		return param;
	}
	
	
	/**
	 * 第一班结束打卡是否成功
	 * 
	 * @param schEntry
	 *            班表明细
	 * @param cards
	 * @return
	 */
	public TimeParam isFinishEndCardByOffice1(ScheduleEntryInfo schEntry,List cards) {

		//早退时间
		int earlyTime=0;
		if(schEntry.getEarlyTime()!=null)
		{
			if(schEntry.getEarlyTime().intValue()>60)
			{
				//earlyTime=60;				
			}else
			{
				//earlyTime=schEntry.getEarlyTime().intValue();				
			}
		}
		//前提打卡时间
		int aheadTime=30;
		if(schEntry.getSb2()!=null)
		{
			aheadTime=schEntry.getSb2().intValue();			
		}
		
		boolean isNextDay = false;
		TimeParam param = new TimeParam();
		
		if (schEntry.getEt1() != null) {
			// 班表结束打卡时间
			long etm = schEntry.getEt1().getMinutes()
					+ schEntry.getEt1().getHours() * 60;
			// 当天到下次上班的时间（最早，即使有效时间）
			long roundstm = schEntry.getSt2().getMinutes()
					+ schEntry.getSt2().getHours() * 60  - aheadTime;

			// 时间范围内卡
			for (int i = 0; i < cards.size(); i++) {
				CardRecordInfo recordInfo = (CardRecordInfo) cards.get(i);
				long ltm = recordInfo.getBizTime().getMinutes()
						+ recordInfo.getBizTime().getHours() * 60;

				// 跨日
				if (!compWorkAndCurrByDate(schEntry.getSchDate(),recordInfo.getBizDate())) {
					// 跨日时间
					ltm += 24 * 60;
					isNextDay = true;
				}
				if (schEntry.getSt1().compareTo(schEntry.getEt1()) > 0) {
					// 第二天，跨日
					isNextDay = true;
					// 结束时间为第二天
					etm += 24 * 60;
				}
				
				//早退使用
				//该班第一班下班时间减去早退时间
				long etm1 = etm-earlyTime;

				if (etm <= ltm && ltm < roundstm) {
					param.isNextDay = isNextDay;
					// 在下次上班时间内打卡，找打结束打卡时间
					param.isFinish = true;
					param.isFind = true;

					// 非请假单虚拟记录,请假时间不作记录
					if(recordInfo.getId()!=null)
					{
						//实际打卡
						param.cardTime = recordInfo.getBizTime();						
					}
					// break;
				}else if(etm1<=ltm&&ltm<etm)
				{
					// 早退
					param.isNextDay = isNextDay;
					param.isFind = true;
					if(recordInfo.getId()!=null)
					{
						//实际打卡
						param.cardTime = recordInfo.getBizTime();						
					}
				}
			}

		}
		return param;
	}
	
	/**
	 * 第二班开始打卡是否成功
	 * 
	 * @param schEntry
	 *            班表明细
	 * @param cards
	 * @return
	 */
	public TimeParam isFinishStartCardByOffice2(ScheduleEntryInfo schEntry,
			List cards) {
		//前提打卡时间
		int aheadTime=30;
		if(schEntry.getSb2()!=null)
		{
			aheadTime=schEntry.getSb2().intValue();			
		}
		
		//迟到时间
		int lateDealLine=0;
		if(schEntry.getLateTime()!=null)
		{
			lateDealLine=schEntry.getLateTime().intValue();
		}
		

		//早退时间
		int earlyTime=0;
		if(schEntry.getEarlyTime()!=null)
		{
			//earlyTime=schEntry.getEarlyTime().intValue();
		}
		TimeParam param = new TimeParam();

		// 班表第一打卡时间
		long stm = schEntry.getSt2().getMinutes()
				+ schEntry.getSt2().getHours() * 60;
		//该班第一班下班时间减去早退时间
		long etm1 = schEntry.getEt2().getMinutes()+ schEntry.getEt2().getHours() * 60-earlyTime;
		
		//第二天
		if(stm>etm1)
		{
			etm1+=24*60;
		}
		// 提前打卡
		long roundtm = stm - aheadTime;
		long lateRoundtm = stm + lateDealLine;
		// 时间范围内卡
		for (int i = 0; i < cards.size(); i++) {
			CardRecordInfo recordInfo = (CardRecordInfo) cards.get(i);
			//打卡时间
			long ftm = recordInfo.getBizTime().getMinutes()
					+ recordInfo.getBizTime().getHours() * 60;
			//第二天
			if (!compWorkAndCurrByDate(schEntry.getSchDate(),recordInfo.getBizDate()))  {
				ftm+=24*60;
			}
			if (roundtm <= ftm && ftm <= stm) {
				// 在时间内打卡，找到第一次打卡时间
				param.isFinish = true;
				param.isFind=true;
				// 非请假单虚拟记录,请假时间不作记录
				if(recordInfo.getId()!=null)
				{
					//实际打卡
					param.cardTime = recordInfo.getBizTime();						
				}
				break;
			} else if (ftm > stm && ftm <= lateRoundtm) {
				// 迟到分钟
				long lateMin = ftm - stm;
				param.isFinish = false;
				param.isFind=true;
				// 非请假单虚拟记录，请假时间不作记录
				if(recordInfo.getId()!=null)
				{
					//实际打卡
					param.cardTime = recordInfo.getBizTime();				
				}
				param.lateTime = lateMin;
				break;
			}else if(ftm>lateRoundtm&&etm1>ftm)
			{
				//旷工 时间
				long absentTime=ftm-stm;
				param.absentTime=absentTime;
				param.isFind=true;
				if(recordInfo.getId()!=null)
				{
					//实际打卡
					param.cardTime = recordInfo.getBizTime();				
				}			
				break;
			}
		}
		//表示没有找到任何打卡记录，计算该班次第一班的旷工时间
		if(!param.isFind)
		{
			param.absentTime=etm1-stm;
		}

		return param;
	}
	
	/**
	 * 第二班开始打卡是否成功(集团逻辑)
	 * 
	 * @param schEntry
	 *            班表明细
	 * @param cards
	 * @return
	 */
	public TimeParam isFinishStartCardByOffice2ByGroup(ScheduleEntryInfo schEntry,
			List cards) {
		//前提打卡时间
		int aheadTime=30;
		if(schEntry.getSb2()!=null)
		{
			aheadTime=schEntry.getSb2().intValue();			
		}
		
		//迟到时间
		int lateDealLine=0;
		if(schEntry.getLateTime()!=null)
		{
			lateDealLine=schEntry.getLateTime().intValue();
		}
		

		//早退时间
		int earlyTime=0;
		if(schEntry.getEarlyTime()!=null)
		{
			//earlyTime=schEntry.getEarlyTime().intValue();
		}
		TimeParam param = new TimeParam();

		// 班表第一打卡时间
		long stm = schEntry.getSt2().getMinutes()
				+ schEntry.getSt2().getHours() * 60;
		//该班第一班下班时间减去早退时间
		long etm1 = schEntry.getEt2().getMinutes()+ schEntry.getEt2().getHours() * 60-earlyTime;
		// 提前打卡
		long roundtm = stm - aheadTime;
		long lateRoundtm = stm + lateDealLine;
		//如果迟到时间大于结束下班时间，取下班时间
		if(lateRoundtm>etm1)
		{
			lateRoundtm=etm1;
		}
		
		//第二天
		if(stm>etm1)
		{
			etm1+=24*60;
		}
		// 时间范围内卡
		for (int i = 0; i < cards.size(); i++) {
			CardRecordInfo recordInfo = (CardRecordInfo) cards.get(i);
			//打卡时间
			long ftm = recordInfo.getBizTime().getMinutes()
					+ recordInfo.getBizTime().getHours() * 60;
			//第二天
			if (!compWorkAndCurrByDate(schEntry.getSchDate(),recordInfo.getBizDate()))  {
				ftm+=24*60;
			}
			if (roundtm <= ftm && ftm <= stm) {
				// 在时间内打卡，找到第一次打卡时间
				param.isFinish = true;
				param.isFind=true;
				// 非请假单虚拟记录,请假时间不作记录
				if(recordInfo.getId()!=null)
				{
					//实际打卡
					param.cardTime = recordInfo.getBizTime();						
				}
				break;
			} else if (ftm > stm && ftm <= lateRoundtm) {
				// 迟到分钟
				long lateMin = ftm - stm;
				param.isFinish = false;
				param.isFind=true;
				// 非请假单虚拟记录，请假时间不作记录
				if(recordInfo.getId()!=null)
				{
					//实际打卡
					param.cardTime = recordInfo.getBizTime();				
				}
				param.lateTime = lateMin;
				break;
			}
		}

		return param;
	}
	
	/**
	 * 第二班结束打卡是否成功
	 * 
	 * @param schEntry
	 *            班表明细
	 * @param cards
	 * @return
	 */
	public TimeParam isFinishEndCardByOffice2(ScheduleEntryInfo schEntry,List cards) {
		
		//早退时间
		int earlyTime=0;
		if(schEntry.getEarlyTime()!=null)
		{
			//earlyTime=schEntry.getEarlyTime().intValue();
		}
		//新班次第一班前提打卡时间
		//前提打卡时间
		int aheadTime=120;
		if(schEntry.getSb1()!=null)
		{
			aheadTime=schEntry.getSb1().intValue();			
		}
		//新班次第二班前提打卡时间
		//前提打卡时间		
		int aheadTime2=30;
		if(schEntry.getSb2()!=null)
		{
			aheadTime2=schEntry.getSb2().intValue();			
		}
		boolean isNextDay = false;
		TimeParam param = new TimeParam();
		
		if (schEntry.getEt2() != null) {
			// 班表结束打卡时间
			long etm = schEntry.getEt2().getMinutes()
					+ schEntry.getEt2().getHours() * 60;
			// 当天到下次上班的时间（最早，即使有效时间）
			long roundstm = schEntry.getSt1().getMinutes()
					+ schEntry.getSt1().getHours() * 60  - aheadTime+24*60;
			
			//早退使用
			//该班第二班下班时间减去早退时间
			long etm1 = etm-earlyTime;
			
			// 班表第一打卡时间
			long stm = schEntry.getSt2().getMinutes()
					+ schEntry.getSt2().getHours() * 60;
			//该班第一班下班时间减去早退时间
			

			// 时间范围内卡
			for (int i = 0; i < cards.size(); i++) {
				CardRecordInfo recordInfo = (CardRecordInfo) cards.get(i);
				long ltm = recordInfo.getBizTime().getMinutes()
						+ recordInfo.getBizTime().getHours() * 60;
				long tmpEtm=etm;
				long tmpEtm1=etm1;

				// 跨日
				if (!compWorkAndCurrByDate(schEntry.getSchDate(),recordInfo.getBizDate())) {
					// 跨日时间
					ltm += 24 * 60;
					isNextDay = true;
				}
				if (schEntry.getSt1().compareTo(schEntry.getEt2()) > 0) {
					// 第二天，跨日
					isNextDay = true;
					// 结束时间为第二天
					tmpEtm += 24 * 60;
					tmpEtm1 += 24 * 60;
				}
				
				if(ltm<=stm)
				{
					//该班第一班已经找到
					param.isFirstFind=true;
				}
			
				if (tmpEtm <= ltm && ltm < roundstm) {
				    if(!param.isFinish)
				    {
						param.isNextDay = isNextDay;
						// 在下次上班时间内打卡，找打结束打卡时间
						param.isFinish = true;
						param.isFind=true;

						// 非请假单虚拟记录,请假时间不作记录
						if(recordInfo.getId()!=null)
						{
							//实际打卡
							param.cardTime = recordInfo.getBizTime();						
						}				    	
				    }
					// break;
				}else if(tmpEtm1<=ltm&&ltm<tmpEtm)
				{
				    if(!param.isFinish)
				    {
						// 早退
						param.isFind=true;
						param.isNextDay = isNextDay;
						param.earlyTime=tmpEtm-ltm;
						if(recordInfo.getId()!=null)
						{
							//实际打卡
							param.cardTime = recordInfo.getBizTime();						
						}				    	
				    }
				}else if(stm<ltm&&ltm<tmpEtm1)
					{
					    if(!param.isFinish)
					    {
							//迟到
							param.isFind=true;
							param.isFinish = false;
							param.lateTime=ltm-stm;
							if(recordInfo.getId()!=null)
							{
								//实际打卡
								param.cardTime = recordInfo.getBizTime();						
							}					    	
					    }
					}					
			}
			
			//表示没有找到任何打卡记录，计算该班次第一班的旷工时间
			if(!param.isFind)
			{
				param.absentTime=etm-stm;
			}else
			{
				if(param.isFinish)
				{
					//该班第一班已经找到
					if(param.isFirstFind)
					{
						param.lateTime=0;
					}
					//找到下班节点，但可能下午上班迟到
					if(param.lateTime>0)
					{
						param.isFinish=false;
					}	
				}else{
					//没找到下班节点，可能早退
					if(param.lateTime>0)
					{
						param.earlyTime=etm-(stm+param.lateTime);
						param.isFinish=false;
						param.lateTime=0;
					}	
				}			
			}				

		}
		return param;
	}	
	
	protected ArrayList getCardRecordYesterDay(Context ctx, String personid, Date d) {
		try {
			Calendar c = Calendar.getInstance();
			c.setTime(d);
			c.set(Calendar.HOUR, 23);
			c.set(Calendar.MINUTE, 59);
			c.set(Calendar.SECOND, 59);
			Date endDate = c.getTime();
			c.setTime(d);
			c.set(Calendar.HOUR, 0);
			c.set(Calendar.MINUTE, 0);
			c.set(Calendar.SECOND, 0);
			c.add(Calendar.DAY_OF_YEAR, -1);
			Date startDate = c.getTime();
			EntityViewInfo evi = new EntityViewInfo();
			FilterInfo filter = new FilterInfo();
			filter.getFilterItems().add(new FilterItemInfo("emp", personid));
			filter.getFilterItems().add(
					new FilterItemInfo("BizDate", startDate,
							CompareType.GREATER_EQUALS));
			filter.getFilterItems().add(
					new FilterItemInfo("BizDate", endDate,
							CompareType.LESS_EQUALS));
			SorterItemCollection sic = new SorterItemCollection();
			sic.add(new SorterItemInfo("bizDate"));
			sic.add(new SorterItemInfo("bizTime"));
			evi.setFilter(filter);
			evi.setSorter(sic);
			CardRecordCollection cards = CardRecordFactory
					.getLocalInstance(ctx).getCardRecordCollection(evi);
			Iterator it = cards.iterator();
			ArrayList ar = new ArrayList();
			while (it.hasNext()) {
				CardRecordInfo info = (CardRecordInfo) it.next();
				ar.add(info);
			}

			return ar;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}
	
	public static boolean compWorkAndCurrByDate(Date workDay, Date currTime) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(workDay);
		c2.setTime(currTime);
		if (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR)
				&& (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH))
				&& c1.get(Calendar.DAY_OF_MONTH) == c2
						.get(Calendar.DAY_OF_MONTH)) {
			return true;
		} else {
			return false;
		}
	}
}
